﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Xml;
using System.Windows.Forms;
using System.Diagnostics;

namespace RemoteUser
{
    //注意与伴侣的交互需要加回车 0x0a
    class SendAndRecv
    {       
        /// <summary>
        /// 发送登录请求报文
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        /// <param name="pwd"></param>
        public static void SendLoginRequest(NetworkStream netstream, string ID, string pwd)
        {   
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "31");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "pwd", pwd);
            TranslateXml.EndXml(xmlWriter);
        }
        /// <summary>
        /// 发送PLC列表请求报文
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        public static void SendPLCListRequest(NetworkStream netstream, string ID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "33");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.EndXml(xmlWriter);
        }   
        /// <summary>
        /// 发送退出报文
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        public static void SendLogoutRequest(NetworkStream netstream, string ID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "53");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.EndXml(xmlWriter);
        }
        /// <summary>
        /// 发送强制退出的反馈，暂时是必然退出成功
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        public static void SendForcedLogoutRespond(NetworkStream netstream, string ID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "56");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "returnCode", "0");
            TranslateXml.AppendElement(xmlWriter, "msg", "");
            TranslateXml.EndXml(xmlWriter); 
        }
        /// <summary>
        /// 发送PLC联系信息请求报文
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        /// <param name="PLCID"></param>
        public static void SendPLCConnInfoRequest(NetworkStream netstream, string ID,string PLCID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "35");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "PLCID", PLCID);
            
            TranslateXml.EndXml(xmlWriter);
        }
        /// <summary>
        /// 发送PLC关键参数请求报文
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        /// <param name="PLCID"></param>
        public static void SendPLCKeyParmsRequest(NetworkStream netstream,string ID,string PLCID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "37");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "PLCID", PLCID);
            TranslateXml.EndXml(xmlWriter);
        }
        /// <summary>
        /// 发送PLC全部参数请求报文
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        /// <param name="PLCID"></param>
        public static void SendPLCAllParmsRequest(NetworkStream netstream,string ID, string PLCID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "39");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "PLCID", PLCID);
            TranslateXml.EndXml(xmlWriter);
        }
        /// <summary>
        /// 发送远程桌面请求报文
        /// </summary>
        /// <param name="netstream"></param>
        /// <param name="ID"></param>
        /// <param name="PLCID"></param>
        public static void SendRemoteDesktopRequest(NetworkStream netstream, 
                                                        string ID, 
                                                        string PLCID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "49");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "PLCID", PLCID);
            TranslateXml.EndXml(xmlWriter);
        }

        public static void SendDetailAbnormalInfoRequest(NetworkStream netstream, 
                                                            string ID, 
                                                            string PLCID, 
                                                            string startTime, 
                                                            string endTime)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "41");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "PLCID", PLCID);
            TranslateXml.AppendElement(xmlWriter, "faultTimeStart", startTime);
            TranslateXml.AppendElement(xmlWriter, "faultTimeEnd", endTime);
            TranslateXml.EndXml(xmlWriter);
        }

        public static void SendOldPersonalInfoRequest(NetworkStream netstream, string ID)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "43");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.EndXml(xmlWriter);
        }

        public static void SendNewPersonalInfoRequest(NetworkStream netstream,
                                                        string ID,
                                                        string oldPwd,
                                                        string newPwd,
                                                        string name,
                                                        string tel,
                                                        string email)
        {
            XmlWriter xmlWriter = TranslateXml.InitXml(netstream);
            TranslateXml.AppendElement(xmlWriter, "ver", "1");
            TranslateXml.AppendElement(xmlWriter, "type", "45");
            TranslateXml.AppendElement(xmlWriter, "userID", ID);
            TranslateXml.AppendElement(xmlWriter, "userType", "1");
            TranslateXml.AppendElement(xmlWriter, "oldPwd", oldPwd);
            TranslateXml.AppendElement(xmlWriter, "newPwd", newPwd);
            TranslateXml.AppendElement(xmlWriter, "name", name);
            TranslateXml.AppendElement(xmlWriter, "tel", tel);
            TranslateXml.AppendElement(xmlWriter, "email", email);
            TranslateXml.EndXml(xmlWriter);
        }

        /// <summary>
        /// 接收、解析服务器发来的报文
        /// </summary>
        /// <param name="myClientSocket"></param>
        /// <returns></returns>
        public static XmlDocument pullXmlFromServer(Socket myClientSocket)
        {
            StringBuilder connResult = new StringBuilder();
            StringBuilder tempResult = new StringBuilder();
            byte[] result = new byte[1024];
            ArrayList allBufferList = new ArrayList();
            int i = 0;
            while (true)
            {
                for (i = 0; i < result.Length; i++)
                {
                    result[i] = 0;
                }
                try
                {
                    //通过clientSocket接收数据
                    int receiveNumber = myClientSocket.Receive(result);
                    if (receiveNumber == 0)
                    {
                        MessageBox.Show("受到了0个字符有问题");
                        return null;
                    }
                    for (i = 0; i < receiveNumber; i++)
                    {
                        allBufferList.Add(result[i]);
                    }
                    //临时封装起来的串，用来检测结尾
                    tempResult.AppendFormat("{0}", Encoding.UTF8.GetString(result, 0, receiveNumber));
                    if (tempResult.ToString().Contains("</PLS>"))
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    return null;
                }
            }
            //拼接报文全文，结果存入 connresult 中
            byte[] allBuffer = new byte[allBufferList.Count];
            for (int j = 0; j < allBufferList.Count; j++)
            {
                allBuffer[j] = (byte)allBufferList[j];
            }
            connResult.Append(Encoding.UTF8.GetString(allBuffer, 0, allBufferList.Count));
            //Debug.WriteLine(connResult.ToString());
            Trace.WriteLine(connResult.ToString());
           
            ///解析XML字符串  
            XmlDocument xDocument = new XmlDocument();
            try
            {
                xDocument.LoadXml(connResult.ToString().TrimStart('\n'));
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return null;
            }
            //返回报文
            return xDocument;
            }      
    }
}
